/**   
* @Title: RspUtils.java
* @Package org.xaoyaoyao.cloud.web.rsp
* @Description: TODO
* @author xaoyaoyao
* @date 2018年9月27日 上午8:36:42
* @version V1.0   
*/
package org.xaoyaoyao.cloud.web.rsp;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Component;
import org.xaoyaoyao.cloud.common.constant.Constants;
import org.xaoyaoyao.cloud.common.result.RetCode;
import org.xaoyaoyao.cloud.common.rsp.RetResult;
import org.xaoyaoyao.cloud.common.utils.StringUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: RspUtils
 * @Description: TODO
 * @author xaoyaoyao
 * @date 2018年9月27日 上午8:36:42
 * 
 */
@Slf4j
@Component
public class RspUtils implements MessageSourceAware {

	private static MessageSource messageSource;

	private static final String AN_EMPTY_STRING = "";

	public static Map<String, Object> makeOKRsp() {
		return makeOKRsp(null);
	}

	public static Map<String, Object> makeOKRsp(String language) {
		return makeRsp(RetCode.SUCESS, null, language);
	}

	public static Map<String, Object> makeRsp(int code) {
		return makeRsp(code, null);
	}

	public static Map<String, Object> makeRsp(int code, String language) {
		Map<String, Object> rsp = new HashMap<String, Object>();
		rsp.put(Constants.CODE, code);
		Locale locale = StringUtils.getLocale(language);
		rsp.put(Constants.MSG, getMessageByMessageSource(locale, code, AN_EMPTY_STRING));
		return rsp;
	}

	public static Map<String, Object> makeRsp(Object value) {
		return makeRsp(value, null);
	}

	public static Map<String, Object> makeRsp(Object value, String language) {
		return makeRsp(Constants.DATA, value, RetCode.SUCESS, language);
	}

	public static Map<String, Object> makeRsp(String key, Object value, int code) {
		return makeRsp(key, value, code, null);
	}

	public static Map<String, Object> makeRsp(String key, Object value, int code, String language) {
		Map<String, Object> rsp = new HashMap<String, Object>();
		rsp.put(Constants.CODE, code);
		Locale locale = StringUtils.getLocale(language);
		rsp.put(Constants.MSG, getMessageByMessageSource(locale, code, AN_EMPTY_STRING));
		rsp.put(key, value);
		return rsp;
	}

	public static Map<String, Object> makeRsp(String key, Object value, int code, String err, String language) {
		Map<String, Object> rsp = new HashMap<String, Object>();
		rsp.put(Constants.CODE, code);
		String msg = getMessageByMessageSource(StringUtils.getLocale(language), code, AN_EMPTY_STRING);
		rsp.put(Constants.MSG, msg);
		rsp.put(Constants.ERR, StringUtils.isBlank(err) ? msg : err);
		rsp.put(key, value);
		return rsp;
	}

	public static Map<String, Object> makeErrorRsp() {
		return makeErrorRsp(null);
	}

	public static Map<String, Object> makeErrorRsp(String language) {
		return makeRsp(RetCode.SYSERROR, language);
	}

	public static Map<String, Object> makeRsp(RetResult<Object> retResult) {
		return makeRsp(retResult, null);
	}

	public static Map<String, Object> makeRsp(RetResult<Object> retResult, String language) {
		return makeRsp(retResult, language, retResult.getObjs());
	}

	public static Map<String, Object> makeRsp(RetResult<Object> retResult, String language, Object... formatVal) {
		if (null == retResult) {
			return makeOKRsp(null);
		}
		Map<String, Object> rsp = new HashMap<String, Object>();
		int code = retResult.getCode();
		rsp.put(Constants.CODE, code);
		Locale locale = StringUtils.getLocale(language);
		formatVal = (null == formatVal || formatVal.length <= 0) ? retResult.getObjs() : formatVal;
		String msg = getMessageByMessageSource(locale, code, formatVal);
		Object obj = retResult.getData();
		rsp.put(Constants.MSG, msg);
		if (null != obj) {
			rsp.put(Constants.DATA, obj);
		}
		return rsp;
	}

	public static Map<String, Object> makeErrRsp(String err) {
		return makeRsp(RetCode.SYSERROR, err, null);
	}

	public static Map<String, Object> makeErrRsp(String err, String language) {
		return makeRsp(RetCode.SYSERROR, err, language);
	}

	public static Map<String, Object> makeOpsFailedRsp(String err) {
		return makeOpsFailedRsp(err, null);
	}

	public static Map<String, Object> makeOpsFailedRsp(String err, String language) {
		return makeRsp(RetCode.OPERATION_FAILED, err, language);
	}

	public static Map<String, Object> makeRsp(int code, String err, String language) {
		Map<String, Object> rsp = new HashMap<String, Object>();
		rsp.put(Constants.CODE, code);
		String msg = getMessageByMessageSource(StringUtils.getLocale(language), code, AN_EMPTY_STRING);
		rsp.put(Constants.MSG, msg);
		rsp.put(Constants.ERR, StringUtils.isBlank(err) ? msg : err);
		return rsp;
	}

	public static Map<String, Object> makeRetResultRsp(RetResult<Object> retResult) {
		return makeRetResultRsp(retResult, null);
	}

	public static Map<String, Object> makeRetResultRsp(RetResult<Object> retResult, String err) {
		return makeRetResultRsp(retResult, null, null);
	}

	public static Map<String, Object> makeRetResultRsp(RetResult<Object> retResult, String err, String language) {
		return makeRetResultRsp(retResult, err, language, AN_EMPTY_STRING);
	}

	public static Map<String, Object> makeRetResultRsp(RetResult<Object> retResult, String err, String language, Object... formatVal) {
		if (null == retResult) {
			return makeOKRsp(null);
		}
		Map<String, Object> rsp = new HashMap<String, Object>();
		int code = retResult.getCode();
		rsp.put(Constants.CODE, code);
		Locale locale = StringUtils.getLocale(language);
		formatVal = (null == formatVal || formatVal.length <= 0) ? retResult.getObjs() : formatVal;
		String msg = getMessageByMessageSource(locale, code, formatVal);
		Object obj = retResult.getData();
		rsp.put(Constants.MSG, msg);
		rsp.put(Constants.ERR, StringUtils.isBlank(err) ? StringUtils.isNotBlank(retResult.getErr()) ? retResult.getErr() : msg : err);
		if (null != obj) {
			rsp.put(Constants.DATA, obj);
		}
		return rsp;
	}

	@Override
	public void setMessageSource(MessageSource messageSource) {
		RspUtils.messageSource = messageSource;
	}

	public static String getMessageByMessageSource(Locale locale, Object code, Object... formatVal) {
		try {
			if (null == code) {
				return AN_EMPTY_STRING;
			}
			locale = null == null ? Locale.CHINA : locale;
			String message = null;
			if (null == formatVal || formatVal.length <= 0) {
				message = messageSource.getMessage(code + AN_EMPTY_STRING, null, locale);
			} else {
				message = messageSource.getMessage(code + AN_EMPTY_STRING, formatVal, locale);
			}
			return StringUtils.isNotBlank(message) ? message : AN_EMPTY_STRING;
		} catch (Exception e) {
			log.error(">>>>>>>> The code >> {}, the locale >> {}", code, locale);
			log.error(e.getMessage(), e);
			return AN_EMPTY_STRING;
		}
	}
}
